﻿using System;
using System.Collections.Generic;

using Microsoft.Xna.Framework;

namespace Spacer {
	public class SolarSysGenerator : Generator {
		public SolarSysGenerator(SolarSys world) : base() {
			World = world;
            SeedOffset = 0;
		}

		public SolarSysGenerator(SolarSys world, int seed) : base(seed) {
			World = world;
            SeedOffset = 0;
		}

		// ----------

		public override void Generate()
        {
			Sun sun = new Sun(World, Seed + SeedOffset);
            SeedOffset++;

            int numPlanets = Random.Next(2, 7);
            List<Planet> planets = new List<Planet>(numPlanets);
            
            //generate Planets & double their position if they're intersecting with an old planet
            for (int i = 0; i < numPlanets; i++)
            {
                Planet newPlanet = new Planet(World, Seed + SeedOffset);
                SeedOffset++;

                double angle = Random.NextDouble() * MathHelper.TwoPi;
                Vector2 pos = new Vector2((float)Math.Cos(angle), (float)Math.Sin(angle));
                pos *= Random.Next(60, 120);
                newPlanet.Position = pos;

                BoundingSphere curPlanet = new BoundingSphere(new Vector3(newPlanet.Position, 0), newPlanet.Radius * 1.5f);
                foreach(Planet prevPlanet in planets)
                {
                    BoundingSphere oldPlanet = new BoundingSphere(new Vector3(prevPlanet.Position, 0), prevPlanet.Radius * 1.5f);
                    while (curPlanet.Intersects(oldPlanet))
                    {
                        newPlanet.Position *= 1.5f;
                        curPlanet.Center *= 1.5f;
                        
                    }
                }
                planets.Add(newPlanet);
            }
            
            //generate asteroids
            int numAsteroidFields = Random.Next(1, 5);

            for (int i = 0; i < numAsteroidFields; i++)
            {
                int fieldSize = Random.Next(7, 15);
                int numAsteroids = Random.Next(15,35);

                double angle = Random.NextDouble() * MathHelper.TwoPi;
                Vector2 FieldCenter = new Vector2((float)Math.Cos(angle), (float)Math.Sin(angle));
                FieldCenter *= Random.Next(70, 130);

                BoundingSphere asteroidFieldArea = new BoundingSphere(new Vector3(FieldCenter, 0), fieldSize);

                foreach (Planet prevPlanet in planets)
                {
                    BoundingSphere oldPlanet = new BoundingSphere(new Vector3(prevPlanet.Position, 0), prevPlanet.Radius);
                    while (asteroidFieldArea.Intersects(oldPlanet))
                    {
                        FieldCenter *= 1.25f;
                        asteroidFieldArea.Center *= 1.25f;
                    }
                }

				List<Asteroid> asteroids = new List<Asteroid>();
                for (int j = 0; j < numAsteroids; j++)
                {
                    Asteroid newAsteroid = new Asteroid(World);

                    angle = Random.NextDouble() * MathHelper.TwoPi;
                    Vector2 pos = new Vector2((float)Math.Cos(angle), (float)Math.Sin(angle));
                    pos *= Random.Next(1, fieldSize);
                    newAsteroid.Position = pos + FieldCenter;

                    newAsteroid.Angle = (float)Random.NextDouble() * MathHelper.TwoPi;
                    //newAsteroid.AngularVelocity = (float)Random.NextDouble() - 0.5f;

					
					BoundingSphere newAsteroidCheck = new BoundingSphere(new Vector3(newAsteroid.Position, 0), 1.5f);

					foreach (Asteroid prevAsteroid in asteroids)
					{
						BoundingSphere oldAsteroidCheck = new BoundingSphere(new Vector3(prevAsteroid.Position, 0), 1.5f);
						while (newAsteroidCheck.Intersects(oldAsteroidCheck))
						{
							pos *= 1.25f;
							newAsteroid.Position = pos + FieldCenter;
							newAsteroidCheck = new BoundingSphere(new Vector3(newAsteroid.Position, 0), 1.5f);
						}
					}

					asteroids.Add( newAsteroid );
                }
            }

            int numEnemies = Random.Next(3, 6);
            for (int i = 0; i < numEnemies; i++)
            {
                Enemy newEnemy = new Enemy(World);

                double angle = Random.NextDouble() * MathHelper.TwoPi;
                Vector2 pos = new Vector2((float)Math.Cos(angle), (float)Math.Sin(angle));
                pos *= Random.Next(25, 50);
                newEnemy.Position = pos;
                newEnemy.Angle = (float)Random.NextDouble() * MathHelper.TwoPi;
            }
		}

        // ----------

        public SolarSys World { get; private set; }

        private int SeedOffset;
	}
}
